<template>
  <div id="studentInfoPage">
    <div style="display: flex; justify-content: space-between">
      <!-- 搜索栏 -->
      <a-form layout="inline" :model="searchParam" @finish="doSearch">
        <a-form-item label="姓名">
          <a-input v-model:value="searchParam.studentName" placeholder="请输入姓名" allow-clear />
        </a-form-item>
        <a-form-item label="学号">
          <a-input v-model:value="searchParam.studentNumber" placeholder="请输入学号" allow-clear />
        </a-form-item>
        <a-form-item label="班级">
          <a-input v-model:value="searchParam.className" placeholder="请输入班级" allow-clear />
        </a-form-item>
        <a-form-item label="状态">
          <a-select ref="select" v-model:value="searchParam.state" style="width: 120px">
            <a-select-option value="">全部</a-select-option>
            <a-select-option :value="0">在读</a-select-option>
            <a-select-option :value="1">毕业</a-select-option>
            <a-select-option :value="2">休学</a-select-option>
            <a-select-option :value="3">退学</a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item>
          <a-button type="primary" html-type="submit"> 搜索 </a-button>
        </a-form-item>
      </a-form>
      <a-button type="primary" size="large" @click="showAddModel">新增学生</a-button>
    </div>
    <div style="margin-bottom: 32px"></div>
    <!-- 表格 -->
    <a-table
      :columns="columns"
      :data-source="dataList"
      :pagination="pagination"
      @change="doTableChange"
    >
      <template #bodyCell="{ column, record }">
        <template v-if="column.dataIndex === 'studentAvatar'">
          <a-image :src="record.studentAvatar" :width="60" />
        </template>
        <template v-else-if="column.dataIndex === 'gender'">
          {{ record.gender === 0 ? '女' : '男' }}
        </template>
        <template v-else-if="column.dataIndex === 'state'">
          {{ stateDict[record.state] }}
        </template>
        <template v-else-if="column.dataIndex === 'enrollmentTime'">
          {{ dayjs(record.enrollmentTime).format('YYYY-MM-DD') }}
        </template>
        <template v-else-if="column.key === 'action'">
          <a-space>
            <a-button type="primary" @click="showUpdateModel(record.id)">修改</a-button>
            <a-button type="primary" danger @click="doDelete(record.id)">删除</a-button>
          </a-space>
        </template>
      </template>
    </a-table>
    <a-modal v-model:open="addModel" title="添加学生" @ok="doAdd">
      <div style="height: 16px"></div>
      <a-form
        :model="formDataAdd"
        name="addStudent"
        :label-col="{ span: 6 }"
        :wrapper-col="{ span: 16 }"
        autocomplete="off"
      >
        <a-form-item
          label="姓名"
          name="studentName"
          :rules="[{ required: true, message: '请输入姓名' }]"
        >
          <a-input v-model:value="formDataAdd.studentName" />
        </a-form-item>
        <a-form-item
          label="学号"
          name="studentNumber"
          :rules="[{ required: true, message: '请输入学号' }]"
        >
          <a-input v-model:value="formDataAdd.studentNumber" />
        </a-form-item>
        <a-form-item label="头像" name="studentAvatar">
          <a-upload
            list-type="picture-card"
            :show-upload-list="false"
            :custom-request="handleUpload"
            :before-upload="beforeUpload"
          >
            <img
              v-if="formDataAdd?.studentAvatar"
              :src="formDataAdd?.studentAvatar"
              alt="avatar"
              style="width: 70px; height: 70px"
            />
            <div v-else>
              <LoadingOutlined v-if="loading"></LoadingOutlined>
              <PlusOutlined v-else></PlusOutlined>
              <div class="ant-upload-text">点击或拖拽上传图片</div>
            </div>
          </a-upload>
        </a-form-item>
        <a-form-item
          label="性别"
          name="gender"
          :rules="[{ required: true, message: '请选择性别' }]"
        >
          <a-radio-group v-model:value="formDataAdd.gender">
            <a-radio :value="0">女</a-radio>
            <a-radio :value="1">男</a-radio>
          </a-radio-group>
        </a-form-item>
        <a-form-item label="班级名称" name="className">
          <a-select v-model:value="formDataAdd.classId">
            <a-select-option v-for="item in classList" :key="item.id" :value="item.id">
              {{ item.className }}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item label="状态" name="state" :rules="[{ required: true, message: '请选择状态' }]">
          <a-radio-group v-model:value="formDataAdd.state">
            <a-radio :value="0">在读</a-radio>
            <a-radio :value="1">毕业</a-radio>
            <a-radio :value="2">休学</a-radio>
            <a-radio :value="3">退学</a-radio>
          </a-radio-group>
        </a-form-item>
        <a-form-item
          label="联系电话"
          name="phone"
          :rules="[{ required: true, message: '请输入联系电话' }]"
        >
          <a-input v-model:value="formDataAdd.phone" />
        </a-form-item>
        <a-form-item
          label="就读学校"
          name="schoolName"
          :rules="[{ required: true, message: '请输入就读学校' }]"
        >
          <a-input v-model:value="formDataAdd.schoolName" />
        </a-form-item>
        <a-form-item label="地址" name="address">
          <a-textarea v-model:value="formDataAdd.address" />
        </a-form-item>
      </a-form>
    </a-modal>
    <a-modal v-model:open="updateModel" title="更新学生信息" @ok="doUpdate">
      <div style="height: 16px"></div>
      <a-form
        :model="formDataUpdate"
        name="updateStudent"
        :label-col="{ span: 6 }"
        :wrapper-col="{ span: 16 }"
        autocomplete="off"
      >
        <a-form-item
          label="姓名"
          name="studentName"
          :rules="[{ required: true, message: '请输入姓名' }]"
        >
          <a-input v-model:value="formDataUpdate.studentName" />
        </a-form-item>
        <a-form-item
          label="学号"
          name="studentNumber"
          :rules="[{ required: true, message: '请输入学号' }]"
        >
          <a-input v-model:value="formDataUpdate.studentNumber" />
        </a-form-item>
        <a-form-item label="头像" name="studentAvatar">
          <a-upload
            list-type="picture-card"
            :show-upload-list="false"
            :custom-request="handleUpload"
            :before-upload="beforeUpload"
          >
            <img
              v-if="formDataUpdate?.studentAvatar"
              :src="formDataUpdate?.studentAvatar"
              alt="avatar"
              style="width: 70px; height: 70px"
            />
            <div v-else>
              <LoadingOutlined v-if="loading"></LoadingOutlined>
              <PlusOutlined v-else></PlusOutlined>
              <div class="ant-upload-text">点击或拖拽上传图片</div>
            </div>
          </a-upload>
        </a-form-item>
        <a-form-item
          label="性别"
          name="gender"
          :rules="[{ required: true, message: '请选择性别' }]"
        >
          <a-radio-group v-model:value="formDataUpdate.gender">
            <a-radio :value="0">女</a-radio>
            <a-radio :value="1">男</a-radio>
          </a-radio-group>
        </a-form-item>
        <a-form-item label="班级名称" name="className">
          <a-select v-model:value="formDataUpdate.classId">
            <a-select-option v-for="item in classList" :key="item.id" :value="item.id">
              {{ item.className }}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item label="状态" name="state" :rules="[{ required: true, message: '请选择状态' }]">
          <a-radio-group v-model:value="formDataUpdate.state">
            <a-radio :value="0">在读</a-radio>
            <a-radio :value="1">毕业</a-radio>
            <a-radio :value="2">休学</a-radio>
            <a-radio :value="3">退学</a-radio>
          </a-radio-group>
        </a-form-item>
        <a-form-item
          label="入学时间"
          name="enrollmentTime"
          :rules="[{ required: true, message: '请输入入学时间' }]"
        >
          <a-date-picker v-model:value="enroDate" />
        </a-form-item>
        <a-form-item
          label="联系电话"
          name="phone"
          :rules="[{ required: true, message: '请输入联系电话' }]"
        >
          <a-input v-model:value="formDataUpdate.phone" />
        </a-form-item>
        <a-form-item
          label="就读学校"
          name="schoolName"
          :rules="[{ required: true, message: '请输入就读学校' }]"
        >
          <a-input v-model:value="formDataUpdate.schoolName" />
        </a-form-item>
        <a-form-item label="地址" name="address">
          <a-textarea v-model:value="formDataUpdate.address" />
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue'
import dayjs from 'dayjs'
import { message, type UploadProps } from 'ant-design-vue'
import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue'
import {
  addStudentUsingPost,
  deleteStudentUsingPost,
  getStudentByIdUsingGet,
  listStudentByPageUsingPost,
  updateStudentUsingPost,
} from '@/api/studentController.ts'
import { uploadImageUsingPost } from '@/api/fileUploadController.ts'
import type { Dayjs } from 'dayjs'
import { listStudentGroupUsingPost } from '@/api/studentGroupController.ts'

const addModel = ref<boolean>(false)
const updateModel = ref<boolean>(false)

const columns = [
  {
    title: '姓名',
    dataIndex: 'studentName',
  },
  {
    title: '学号',
    dataIndex: 'studentNumber',
  },
  {
    title: '头像',
    dataIndex: 'studentAvatar',
  },
  {
    title: '性别',
    dataIndex: 'gender',
  },
  {
    title: '班级名称',
    dataIndex: 'className',
  },
  {
    title: '联系电话',
    dataIndex: 'phone',
  },
  {
    title: '地址',
    dataIndex: 'userProfile',
  },
  {
    title: '状态',
    dataIndex: 'state',
  },
  {
    title: '入学时间',
    dataIndex: 'enrollmentTime',
  },
  {
    title: '就读学校',
    dataIndex: 'schoolName',
  },
  {
    title: '操作',
    key: 'action',
  },
]

const stateDict = {
  0: '在读',
  1: '毕业',
  2: '休学',
  3: '退学',
}

// 定义数据
const dataList = ref<API.Student[]>([])
const total = ref(0)

// 搜索条件
const searchParam = reactive<API.StudentQueryRequest>({
  current: 1,
  pageSize: 10,
  studentNumber: '',
  studentName: '',
  className: '',
  state: '',
  enrollmentTime: '',
  schoolName: '',
})

// 分页参数
const pagination = computed(() => {
  return {
    current: searchParam.current,
    pageSize: searchParam.pageSize,
    total: total.value,
    showSizeChanger: true,
    showTotal: (total: number) => `共${total}条`,
  }
})

const doTableChange = (page: any) => {
  searchParam.current = page.current
  searchParam.pageSize = page.pageSize
  fetchData()
}

// 获取数据
const fetchData = async () => {
  const res = await listStudentByPageUsingPost({
    ...searchParam,
  })
  if (res.data.code === 0 && res.data.data) {
    dataList.value = res.data.data.records ?? []
    total.value = res.data.data.total ?? 0
  } else {
    message.error('获取数据失败' + res.data.message)
  }
}

// 页面加载时获取数据，请求一次
onMounted(() => {
  fetchData()
})

const doSearch = () => {
  // 重置页码
  searchParam.current = 1
  fetchData()
}

const doDelete = async (id: number) => {
  if (!id) {
    return
  }
  const res = await deleteStudentUsingPost({ id: id })
  if (res.data.code === 0) {
    message.success('删除成功')
    // 刷新数据
    fetchData()
  } else {
    message.error('删除失败')
  }
}

const formDataAdd = reactive<API.StudentAddRequest>({
  studentName: '',
  studentNumber: '',
  studentAvatar: '',
  gender: undefined,
  classId: undefined,
  className: '',
  phone: '',
  state: undefined,
  enrollmentTime: '',
  schoolName: '',
  address: '',
})
const formDataUpdate = ref<API.StudentUpdateRequest>({
  studentName: '',
  studentNumber: '',
  studentAvatar: '',
  gender: undefined,
  className: '',
  phone: '',
  state: undefined,
  enrollmentTime: '',
  schoolName: '',
  address: '',
})

const enroDate = ref<Dayjs>()
watch(enroDate, (newValue) => {
  formDataUpdate.value.enrollmentTime = newValue?.format('YYYY-MM-DD')
})

const doUpdate = async () => {
  const res = await updateStudentUsingPost({
    ...formDataUpdate.value,
  })
  if (res.data.code === 0 && res.data.data !== null) {
    message.success('更新成功')
    fetchData()
    updateModel.value = false
  } else {
    message.error('更新失败, ' + res.data.message)
  }
}

const doAdd = async () => {
  const res = await addStudentUsingPost({
    ...formDataAdd,
  })
  if (res.data.code === 0 && res.data.data !== null) {
    message.success('添加成功')
    fetchData()
    addModel.value = false
  } else {
    message.error('添加失败, ' + res.data.message)
  }
}

const classList = ref<API.StudentGroup[]>([])

const showAddModel = async () => {
  formDataAdd.studentName = ''
  formDataAdd.studentNumber = ''
  formDataAdd.studentAvatar = ''
  formDataAdd.gender = undefined
  formDataAdd.classId = undefined
  formDataAdd.className = ''
  formDataAdd.state = undefined
  formDataAdd.phone = ''
  formDataAdd.address = ''
  formDataAdd.schoolName = ''
  const resp = await listStudentGroupUsingPost({})
  if (resp.data.code === 0 && resp.data.data) {
    classList.value = resp.data.data ?? []
  } else {
    message.error('获取数据失败' + resp.data.message)
  }
  addModel.value = true
}

const showUpdateModel = async (id: number) => {
  const res = await getStudentByIdUsingGet({ id })
  if (res.data.code === 0 && res.data.data !== null) {
    formDataUpdate.value = {
      ...res.data.data,
    }
    enroDate.value = dayjs(formDataUpdate.value.enrollmentTime)
    const resp = await listStudentGroupUsingPost({})
    if (resp.data.code === 0 && resp.data.data) {
      classList.value = resp.data.data ?? []
    } else {
      message.error('获取数据失败' + resp.data.message)
    }
    updateModel.value = true
  } else {
    message.error('获取数据失败, ' + res.data.message)
  }
}

const loading = ref<boolean>(false)

/**
 * 上传图片
 * @param file
 */
const handleUpload = async ({ file }: any) => {
  loading.value = true
  try {
    const res = await uploadImageUsingPost({}, file)
    if (res.data.code === 0 && res.data.data) {
      message.success('图片上传成功')
      formDataAdd.studentAvatar = res.data.data
      formDataUpdate.value.studentAvatar = res.data.data
    } else {
      message.error('图片上传失败，' + res.data.message)
    }
  } catch (error) {
    console.log('图片上传失败，' + error)
    message.error('图片上传失败，' + error)
  }
  loading.value = false
}

/**
 * 上传前的校验
 * @param file
 */
const beforeUpload = (file: UploadProps['fileList'][number]) => {
  // 校验图片格式
  const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'
  if (!isJpgOrPng) {
    message.error('不支持上传该格式的图片，推荐 jpg 或 png')
  }
  // 校验图片大小
  const isLt2M = file.size / 1024 / 1024 < 2
  if (!isLt2M) {
    message.error('不能上传超过 2M 的图片')
  }
  return isJpgOrPng && isLt2M
}
</script>

<style scoped></style>
